package net.wanglu.www.zzz.rule.sva;

import java.util.HashMap;
import java.util.regex.Pattern;

import net.wanglu.www.zzz.rule.BadEgg;
import net.wanglu.www.zzz.rule.Rule;
import net.wanglu.www.zzz.service.se.nsubj._NSubjTuple;
import edu.stanford.nlp.trees.TreeGraphNode;

public class SPSameAsSubj extends _SvaRule {
	
	public static final Pattern Fish = Pattern.compile("\\bfish\\b|\\bbass\\b|\\bbream\\b|\\bcarp\\b|\\bcod\\b|\\bcrab\\b|\\bdace\\b|\\beel\\b|\\bflounder\\b|\\bherring\\b|\\bhalibut\\b|\\bhake\\b|\\bhaddock\\b|\\blobster\\b|\\bmackerel\\b|\\bperch\\b|\\bpike\\b|\\bplaice\\b|\\broach\\b|\\bskate\\b|\\bsardine\\b|\\bsalmon\\b|\\bshark\\b|\\bsquid\\b|\\bsole\\b|\\btrout\\b|\\bwhale\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern Animal = Pattern.compile("\\bantelope\\b|\\bbison\\b|\\bbighorn\\b|\\bbuffalo\\b|\\bduck\\b|\\bdeer\\b|\\belk\\b|\\belephant\\b|\\bfowl\\b|\\bgoat\\b|\\bgrouse\\b|\\bleopard\\b|\\blion\\b|\\bmoose\\b|\\bpartridge\\b|\\bpeacock\\b|\\bquail\\b|\\brabbit\\b|\\breindeer\\b|\\bsheep\\b|\\bswine\\b|\\btiger\\b|\\bwoodcock\\b|\\bzebra\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern Fly = Pattern.compile("\\baircraft\\b|\\bcraft\\b|\\bhovercraft\\b|\\bsail\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern Person = Pattern.compile("\\bAfghan\\b|\\bAlbanian\\b|\\bAlgerian\\b|\\bAndorran\\b|\\bAngolan\\b|\\bArgentinian\\b|\\bArmenian\\b|\\bAustralian\\b|\\bAustrian\\b|\\bAzerbaijani\\b|\\bBahamian\\b|\\bBahraini\\b|\\bBangladeshi\\b|\\bBarbadian\\b|\\bBelarusian\\b|\\bBelarusan\\b|\\bBelgian\\b|\\bBelizean\\b|\\bBeninese\\b|\\bBhutanese\\b|\\bBolivian\\b|\\bBosnian\\b|\\bTswana\\b|\\bBrazilian\\b|\\bBriton\\b|\\bBruneian\\b|\\bBulgarian\\b|\\bBurkinese\\b|\\bBurmese\\b|\\bBurundian\\b|\\bCambodian\\b|\\bCameroonian\\b|\\bCanadian\\b|\\bCape Verdean\\b|\\bChadian\\b|\\bChilean\\b|\\bChinese\\b|\\bColombian\\b|\\bCongolese\\b|\\bCosta Rican\\b|\\bCroat\\b|\\bCroatian\\b|\\bCuban\\b|\\bCypriot\\b|\\bCzech\\b|\\bDane\\b|\\bDjiboutian\\b|\\bDominican\\b|\\bDominican\\b|\\bEcuadorean\\b|\\bEgyptian\\b|\\bSalvadorean\\b|\\bEnglishman\\b|\\bEnglishwoman\\b|\\bEritrean\\b|\\bEstonian\\b|\\bEthiopian\\b|\\bFijian\\b|\\bFinn\\b|\\bFrenchman\\b|\\bFrenchwoman\\b|\\bGabonese\\b|\\bGambian\\b|\\bGeorgian\\b|\\bGerman\\b|\\bGhanaian\\b|\\bGreek\\b|\\bGrenadian\\b|\\bGuatemalan\\b|\\bGuinean\\b|\\bGuyanese\\b|\\bHaitian\\b|\\bDutchman\\b|\\bDutchwoman\\b|\\bHonduran\\b|\\bHungarian\\b|\\bIcelander\\b|\\bIndian\\b|\\bIndonesian\\b|\\bIranian\\b|\\bIraqi\\b|\\bIrishman\\b|\\bIrishwoman\\b|\\bItalian\\b|\\bJamaican\\b|\\bJapanese\\b|\\bJordanian\\b|\\bKazakh\\b|\\bKenyan\\b|\\bKuwaiti\\b|\\bLaotian\\b|\\bLatvian\\b|\\bLebanese\\b|\\bLiberian\\b|\\bLibyan\\b|\\bLiechtensteiner\\b|\\bLithuanian\\b|\\bLuxembourger\\b|\\bMacedonian\\b|\\bMalagasy\\b|\\bMadagascan\\b|\\bMalawian\\b|\\bMalaysian\\b|\\bMaldivian\\b|\\bMalian\\b|\\bMaltese\\b|\\bMauritanian\\b|\\bMauritian\\b|\\bMexican\\b|\\bMoldovan\\b|\\bMonégasque\\b|\\bMonacan\\b|\\bMongolian\\b|\\bMontenegrin\\b|\\bMoroccan\\b|\\bMozambican\\b|\\bNamibian\\b|\\bNepalese\\b|\\bDutchman\\b|\\bDutchwoman\\b|\\bNetherlander\\b|\\bNew Zealander\\b|\\bNicaraguan\\b|\\bNigerien\\b|\\bNigerian\\b|\\bNorth Korean\\b|\\bNorwegian\\b|\\bOmani\\b|\\bPakistani\\b|\\bPanamanian\\b|\\bPapua New Guinean\\b|\\bGuinean\\b|\\bParaguayan\\b|\\bPeruvian\\b|\\bFilipino\\b|\\bPole\\b|\\bPortuguese\\b|\\bQatari\\b|\\bRomanian\\b|\\bRussian\\b|\\bRwandan\\b|\\bSaudi Arabian\\b|\\bSaudi\\b|\\bScot\\b|\\bSenegalese\\b|\\bSerb\\b|\\bSerbian\\b|\\bSeychellois\\b|\\bSierra Leonian\\b|\\bSingaporean\\b|\\bSlovak\\b|\\bSlovene\\b|\\bSlovenian\\b|\\bSolomon Islander\\b|\\bSomali\\b|\\bSouth African\\b|\\bSouth Korean\\b|\\bSpaniard\\b|\\bSri Lankan\\b|\\bSudanese\\b|\\bSurinamer\\b|\\bSurinamese\\b|\\bSwazi\\b|\\bSwede\\b|\\bSwiss\\b|\\bSyrian\\b|\\bTaiwanese\\b|\\bTajik\\b|\\bTadjik\\b|\\bTanzanian\\b|\\bThai\\b|\\bTogolese\\b|\\bTrinidadian\\b|\\bTobagan\\b|\\bTobagonian\\b|\\bTunisian\\b|\\bTurk\\b|\\bTurkmen\\b|\\bTurkoman\\b|\\bTuvaluan\\b|\\bUgandan\\b|\\bUkrainian\\b|\\bEmirati\\b|\\bBriton\\b|\\bUS citizen\\b|\\bUruguayan\\b|\\bUzbek\\b|\\bVanuatuan\\b|\\bVenezuelan\\b|\\bVietnamese\\b|\\bWelshman\\b|\\bWelshwoman\\b|\\bWestern Samoan\\b|\\bYemeni\\b|\\bYugoslav\\b|\\bZambian\\b|\\bZimbabwean\\b");
	public static final Pattern DenotePerson = Pattern.compile("\\bbuttons\\b|\\bcorps\\b|\\bcounsel\\b|\\blazybones\\b|\\bhelp\\b|\\boffspring\\b|\\bvermin\\b", Pattern.CASE_INSENSITIVE);
	public static final Pattern OthersSPSame = Pattern.compile("\\bbarracks\\b|\\bchassis\\b|\\bcrossroads\\b|\\bheadquarters\\b|\\bhorsepower\\b|\\bLadies\\b|\\bmeans\\b|\\bmews\\b|\\bprecis\\b|\\bseries\\b|\\bspecies\\b|\\bworks\\b|\\bshambles\\b", Pattern.CASE_INSENSITIVE);
	@Override
	public Object applicable(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		if ( super.applicable(objects) == Rule.Inapplicable) return Rule.Inapplicable;
		_NSubjTuple nst = (_NSubjTuple) objects[1];
		if ( !"NP".equals(nst.getSubjectAncestor().value())) return Rule.Inapplicable;
		return Rule.Applicable;
	}

	@Override
	public Object deviseRightSolution(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		return null;
	}

	@Override
	public Object examine(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		HashMap<?, ?> preprocessData = (HashMap<?, ?>) objects[0];
		_NSubjTuple nst =  (_NSubjTuple) objects[1];
		
		if ( this.applicable(preprocessData, nst) == Rule.Inapplicable) return Rule.Inapplicable;
		TreeGraphNode subj = (TreeGraphNode) nst.getSubj();
		
		if ( Fish.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Animal.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Fly.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( Person.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( DenotePerson.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		} else if ( OthersSPSame.matcher(subj.label().word()).find()) {
			BadEgg egg = new BadEgg();
			egg.setViolatedRule(this);
			egg.setProperty(BadEgg.Warning);
			egg.whereIsWrong = nst;
			return egg;
		}
		
		return Rule.Inapplicable;
	}

	@Override
	public Object whyItsWrong(Object... objects) throws Exception {
		// TODO Auto-generated method stub
		sb.clear();
		sb.append("<p>");
		sb.append("单复数同形的名词作主语时，谓语动词的数应遵循概念一致的原则。如果作主语的名词表示的是单数概念，谓语动词就用单数形式；如果作主语的名词表示的是复数概念，谓语动词就用复数形式。");
		sb.append("</p>");			

		return sb.toString();
	}
}
